home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / vgamaze4.zip / ORACLE.CPP < prev    next >
C/C++ Source or Header  |  1994-02-14  |  3KB  |  96 lines

  1. #include "oracle.h"
  2.  
  3. #define TRUE -1
  4. #define FALSE 0
  5.  
  6. oracle::oracle(char *seed,int max_r_n_plus_1)
  7. //      An eight (or fewer) character seed and the upper bound on the
  8. // numbers to be returned specify the random number generator. 
  9.   {
  10.     modulus=max_r_n_plus_1;
  11.     prime=equal_or_larger_prime(modulus);
  12.     // A prime modulus is needed to insure that the number returned from
  13.     // the random number generator are uniformly distributed.
  14.     for (int r_n_index_1=0; ((r_n_index_1 < 8) && (seed[r_n_index_1]));
  15.      r_n_index_1++)        // insert seed
  16.       {
  17.         if (seed[r_n_index_1] < '\0')
  18.           seed[r_n_index_1]=-seed[r_n_index_1];
  19.         r_n[r_n_index_1]=long(seed[r_n_index_1])%prime;
  20.       }
  21.     int r_n_index_2=7;
  22.     while (r_n_index_1 > 0) // right justify
  23.       {
  24.          r_n_index_1--;
  25.          r_n[r_n_index_2]=r_n[r_n_index_1];
  26.          r_n_index_2--;
  27.       }
  28.     while (r_n_index_2 >= 0) // fill with leading 1's
  29.       {
  30.         r_n[r_n_index_2]=1;
  31.         r_n_index_2--;
  32.       }
  33.   }
  34.  
  35. long oracle::equal_or_larger_prime(int starting_value)
  36. //      Try consecutive values until a prime number is found.
  37.   {
  38.     long result=long(starting_value);
  39.     while (! is_prime(result)) result++;
  40.     return result;
  41.   }
  42.  
  43. int oracle::is_prime(long possible_prime)
  44. //      If no number up to the square root of a number evenly divides the
  45. // number, then the number is prime.
  46.   {
  47.     long new_max_divisor;
  48.     int  result=TRUE;
  49.     long max_divisor=possible_prime;
  50.     int  square_root=FALSE;
  51.  
  52.     while (! square_root)
  53.       {
  54.         if ((new_max_divisor=(max_divisor+possible_prime/max_divisor)/2l)
  55.          < max_divisor)
  56.           max_divisor=new_max_divisor;
  57.         else
  58.           square_root=TRUE;
  59.       }  // max_divisor=sqrt(possible_prime) via Newton's method.
  60.     for (long divisor=2l; ((result) && (divisor <= max_divisor)); divisor++)
  61.       result=((divisor*(possible_prime/divisor)) != possible_prime);
  62.     return result;
  63.   }
  64.  
  65. int oracle::random_number()
  66. //     Ignoring initialization, r_n[i] is the sum of the 8 previous values of
  67. // r_n[i] mod prime. r_n[7] is computed until it's within the desired range and
  68. // then it's returned.
  69. //     It is assumed that a "long" can contain the sum of any two "int"s.
  70.   {
  71.     int  r_n_index_1;
  72.     int  r_n_index_2;
  73.     long result;
  74.     long tem_long;
  75.  
  76.     do
  77.       {
  78.         result=r_n[0];
  79.         r_n_index_1=0;
  80.         r_n_index_2=1;
  81.         while (r_n_index_2 < 8)
  82.           {
  83.             tem_long=r_n[r_n_index_2];
  84.             r_n[r_n_index_1]=tem_long;
  85.             result+=tem_long;
  86.             if (result >= prime)
  87.               result-=prime;
  88.             r_n_index_1=r_n_index_2;
  89.             r_n_index_2++;
  90.           }
  91.         r_n[7]=result;
  92.       }
  93.     while (result >= long(modulus));
  94.     return int(result);
  95.   }
  96.